/*
 *  The <paging.h> header file defines some data structures to manage memory paging
 */

#ifndef _I386_PAGING_H
#define _I386_PAGING_H

#include <types.h>

#define PAGE_DIR_SIZE 1024
#define PAGE_TAB_SIZE 1024


// Page/Directory Present
#define PG_NOT_PRESENT          0
#define PG_PRESENT              1
// Page/Directory Write/Read Access
#define PG_READ                 0
#define PG_WRITE                2
// Page/Directory User/Superuser Acceess
#define PG_SUPER                0 
#define PG_USER                 4
// Page Write Trough 
#define PG_PWT_WRITEBACK        0
#define PG_PWT_WRITETHROUGH     8
// Page Cache Disable
#define PG_PCD_ENABLE           0
#define PG_PCD_DISABLE         16
// Page/Directory Accessed
#define PG_NOT_ACCESSED         0
#define PG_ACCESSED            32
// Page Dirty (written) (undefined for Page Directories)
#define PG_NOT_DIRTY            0
#define PG_DIRTY               64


/*
 *  31                                   12 11  9 8 7 6 5 4 3 2 1 0
 *  |                                     | |   | | | | | | | | | |
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 *                                                        P P U W 
 *  <   Page Table/Frame Address 31..12   > X X X 0 0 D A C W - - P
 *                                                        D T S R 
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *     4th Byte   |    3rd Byte   |    2nd Byte   |    1st Byte   |
 *
 *  X X X = OS Reserved
 *
 *  <...> = Page Table or Page Frame address respectively for Page Directory or Page Tables
 *
 */


#pragma pack(1)

typedef struct {
  byte_t access;       // Page Table Access rights (1st Byte) [Mem=4MB]
  byte_t pteaddr_lsb;  // LSB of Page Table Address (2nd Byte)
  word_t pteaddr_msb;  // MSB of Page Table Address (Bytes 3rd and 4th)
} PDE_T;

typedef struct {
  byte_t access;       // Page Frame Access rights (1st Byte) [Mem=4KB]
  byte_t pfraddr_lsb;  // LSB of Page Frame Address (2nd Byte)
  word_t pfraddr_msb;  // MSB of Page Frame Address (Bytes 3rd and 4th)
} PTE_T;

#pragma pack(4)

/* Paging Structure Management Functions Prototypes */

extern void ivmmPTE_setAccess(PTE_T *entry,byte_t value);
extern byte_t ivmmPTE_getAccess(PTE_T *entry);
extern void ivmmPTE_setOsBits(PTE_T *entry,byte_t value);
extern byte_t ivmmPTE_getOsBits(PTE_T *entry);
extern void ivmmPTE_setAddress(PTE_T *entry,dword_t address);
extern dword_t ivmmPTE_getAddress(PTE_T *entry);

extern void ivmmPDE_setAccess(PDE_T *entry,byte_t value);
extern byte_t ivmmPDE_getAccess(PDE_T *entry);
extern void ivmmPDE_setOsBits(PDE_T *entry,byte_t value);
extern byte_t ivmmPDE_getOsBits(PDE_T *entry);
extern void ivmmPDE_setAddress(PDE_T *entry,dword_t address);
extern dword_t ivmmPDE_getAddress(PDE_T *entry);

#endif /* _PAGING_H */
